/****************************************************************************************************
 * 项目：数据定义和外部声明
 * 描述：统一管理全局定义和外部声明。
 ****************************************************************************************************/
/**************************************************0-开始**************************************************/
/**************************************************0-结束**************************************************/
#ifndef _ZHI_H
#define _ZHI_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <math.h>
#include <ctype.h>
#include <math.h>
#include <errno.h>
#include <time.h>
#include <stdarg.h>


#define ZHI_VERSION "0.0.01"
#define MAX_LINE_LEN 1024
/**************************************************o_common.h-开始**************************************************/
typedef struct 虚拟机S 虚拟机;
typedef struct 词法分析器S 词法分析器;
typedef struct class Class;

#define bool char
#define true   1
#define false  0

#ifdef DEBUG /*如果是调试，就执行断言*/
#define ASSERT(条件, 错误信息) \
      do {\
	 if (!(条件)) {\
	    fprintf(stderr, "ASSERT失败! %s:%d 在函数 %s()中: %s\n", \
	       __FILE__, __LINE__, __FUNCTION__, 错误信息); \
	    abort();\
	 	 }\
	        } while (0);
#else
#define ASSERT(条件, 错误信息) ((void)0)
#endif
/*通常有些程序分支是不能被执行到的，如果被执行到，说明程序出错，为检查这种情况定义此宏。将其安插到那些不可能到达的分支中*/
#define 没有达到M()\
   do {\
      fprintf(stderr, "没有达到M: %s:%d 在函数 %s()中\n", \
	 __FILE__, __LINE__, __FUNCTION__);\
	 	  while(1);\
   } while (0);
/**************************************************o_common.h-结束**************************************************/
/**************************************************o_utils.h-开始**************************************************/
void* 内存管理器(虚拟机* 虚拟机S, void* ptr, uint32_t 旧内存大小, uint32_t 新内存大小);

#define 分配指定类型的内存块M(vmPtr, type) \
   (type*)内存管理器(vmPtr, NULL, 0, sizeof(type))
/*分配除主类型mainType外，还需要额外的extraSize大小的内存。用于实现柔性数组的功能。*/
#define 分配除主类型外还需要额外指定大小的内存M(vmPtr, 主类型, 额外大小) \
   (主类型*)内存管理器(vmPtr, NULL, 0, sizeof(主类型) + 额外大小)

#define 分配数组内存M(vmPtr, type, count) \
   (type*)内存管理器(vmPtr, NULL, 0, sizeof(type) * count)

#define 释放数组占用的内存M(vmPtr, arrayPtr, count) \
   内存管理器(vmPtr, arrayPtr, sizeof(arrayPtr[0]) * count, 0)

#define 释放内存M(vmPtr, memPtr) 内存管理器(vmPtr, memPtr, 0, 0)

uint32_t 大于等于v最近的2次幂(uint32_t v);
/*用于存储字符串*/
typedef struct {
   char* str;
   uint32_t 长度;
} ZiFuChuan;
/*用于存储字符串对象（objZiFuChuan）中的字符串*/
typedef struct {
   uint32_t 长度; //除结束'\0'之外的字符个数
   char start[0];  //类似c99中的柔性数组
} 字符值S;  //字符串缓冲区

//声明buffer类型
/*用于定于整个语言的核心存储结构：type##Buffer结构体。专用于存储类型为type的数据缓冲区*/
#define 声明缓冲区类型M(type)\
   typedef struct {\
      /* 数据缓冲区 */    \
      type* 数据缓冲区;\
      /*缓冲区中已使用的元素个数*/\
      uint32_t count;\
      /*缓冲区容量用*/\
      uint32_t 数组容量;\
   } type##Buffer;\
   void type##BufferInit(type##Buffer* buf);\
   void type##BufferFillWrite(虚拟机* 虚拟机S, \
	 type##Buffer* buf, type data, uint32_t fillCount);\
   void type##BufferAdd(虚拟机* 虚拟机S, type##Buffer* buf, type data);\
   void type##BufferClear(虚拟机* 虚拟机S, type##Buffer* buf);

//定义buffer方法
#define 定义缓冲区方法M(type)\
   void type##BufferInit(type##Buffer* buf) {\
      buf->数据缓冲区 = NULL;\
      buf->count = buf->数组容量 = 0;\
   }\
\
   void type##BufferFillWrite(虚拟机* 虚拟机S, \
	 type##Buffer* buf, type data, uint32_t fillCount) {\
      uint32_t newCounts = buf->count + fillCount;\
      if (newCounts > buf->数组容量) {\
	 size_t 旧内存大小 = buf->数组容量 * sizeof(type);\
	 buf->数组容量 = 大于等于v最近的2次幂(newCounts);\
	 size_t 新内存大小 = buf->数组容量 * sizeof(type);\
	 ASSERT(新内存大小 > 旧内存大小, "晕……内存分配！");\
	 buf->数据缓冲区 = (type*)内存管理器(虚拟机S, buf->数据缓冲区, 旧内存大小, 新内存大小);\
      }\
      uint32_t cnt = 0;\
      while (cnt < fillCount) {\
	 buf->数据缓冲区[buf->count++] = data;\
	 cnt++;\
      }\
   }\
\
   void type##BufferAdd(虚拟机* 虚拟机S, type##Buffer* buf, type data) {\
      type##BufferFillWrite(虚拟机S, buf, data, 1);\
   }\
\
   void type##BufferClear(虚拟机* 虚拟机S, type##Buffer* buf) {\
      size_t 旧内存大小 = buf->数组容量 * sizeof(buf->数据缓冲区[0]);\
      内存管理器(虚拟机S, buf->数据缓冲区, 旧内存大小, 0);\
      type##BufferInit(buf);\
   }

声明缓冲区类型M(ZiFuChuan)
#define SymbolTable ZiFuChuanBuffer
typedef uint8_t Byte;
typedef char Char;
typedef int Int;
声明缓冲区类型M(Int)
声明缓冲区类型M(Char)
声明缓冲区类型M(Byte)

typedef enum {
   错误_输入输出,
   错误_内存分配,
   错误_词法分析,
   错误_编译,
   错误_runtime
} 错误类型E;

void 错误报告(void* 词法分析器S,错误类型E errorType, const char* fmt, ...);

void 清理符号表(虚拟机*, SymbolTable* buffer);

#define 输入输出_错误(...)\
   错误报告(NULL, 错误_输入输出, __VA_ARGS__)

#define 内存分配_错误(...)\
   错误报告(NULL, 错误_内存分配, __VA_ARGS__)

#define 词法分析_错误(词法分析器S, ...)\
   错误报告(词法分析器S, 错误_词法分析, __VA_ARGS__)

#define 编译_错误(词法分析器S, ...)\
   错误报告(词法分析器S, 错误_编译, __VA_ARGS__)

#define runtime_错误(...)\
   错误报告(NULL, 错误_runtime, __VA_ARGS__)

#define 默认缓冲区大小M 512
/**************************************************o_utils.h-结束**************************************************/
/**************************************************o_字符集编码Utf8.h-开始**************************************************/
uint32_t 按照UTF8编码的字节数(int value);
uint32_t 解码UTF8编码所需要的字节数(uint8_t byte);
uint8_t 按照UTF8编码写入缓冲区(uint8_t* buf, int value);
int 解码一个经过UTF8编码的字符序列(const uint8_t* bytePtr, uint32_t 长度);
/**************************************************o_字符集编码Utf8.h-结束**************************************************/
/**************************************************o_header_obj.h-开始**************************************************/
typedef enum {
   对象类型_类,   //此项是class类型,以下都是object类型
   对象类型_列表,
   对象类型_散列数组,
   对象类型_模块作用域,
   对象类型_范围,
   对象类型_字符串,
   对象类型_自由变量,
   对象类型_函数,
   对象类型_闭包,
   对象类型_对象实例,
   对象类型_线程
} 对象类型E;  //对象类型

typedef struct objHeader {
   对象类型E type;/*指明对象类型*/
   bool 对象是否可达;	   //对象是否可达
   Class* class;   //对象所属的类
   struct objHeader* next;   //用于链接所有已分配对象
} 对象头S;	  //对象头,用于记录元信息和垃圾回收

typedef enum {
   值类型_未定义,/*未定义*/
   值类型_空,/*表示空值*/
   值类型_假,/*布尔假*/
   值类型_真,/*布尔真*/
   值类型_数字,/*数字类型*/
   值类型_对象   //值为对象,指向对象头
} 值类型S;     //value值类型

typedef struct {
   值类型S type;/*此值的类型*/
   union {
      double num;/*数字和对象*/
      对象头S* objHeader;
   };
} Value;   //通用的值结构

声明缓冲区类型M(Value)/*生成value类型buffer的定义，即ValueBuffer及与ValueBuffer配套的4个操作方法的声明。*/

void 初始化对象头(虚拟机* 虚拟机S, 对象头S* objHeader, 对象类型E objType, Class* class);
/**************************************************o_header_obj.h-结束**************************************************/
/**************************************************o_obj_string.h-开始**************************************************/
typedef struct {
   对象头S objHeader;
   uint32_t hashCode;  //字符串的哈希值
   字符值S value;/*不同对象的值有不同的含义。字符串对象的值就是字符串*/
} 字符串对象S;/*字符串对象*/

uint32_t 计算字符串哈希值(char* str, uint32_t 长度);
void 为字符串计算哈希值并将值存储(字符串对象S* objZiFuChuan);
字符串对象S* 以字符串创建字符串对象(虚拟机* 虚拟机S, const char* str, uint32_t 长度);
/**************************************************o_obj_string.h-结束**************************************************/
/**************************************************o_meta_obj.h-开始**************************************************/
typedef struct {
   对象头S  objHeader;
   SymbolTable moduleVarName;   //模块中的模块变量名
   ValueBuffer moduleVarValue;  //模块中的模块变量值
   字符串对象S*  name;   //模块名
} 模块对象S;   //模块对象

typedef struct {
   对象头S objHeader;
   //具体的字段
   Value fields[0];
} 对象实例S;	//对象实例

模块对象S* 新建对象模块(虚拟机* 虚拟机S, const char* modName);
对象实例S* 新建类的实例(虚拟机* 虚拟机S, Class* class);
/**************************************************o_meta_obj.h-结束**************************************************/
/**************************************************o_obj_fn.h-开始**************************************************/
typedef struct {
   char* fnName;     //函数名
   IntBuffer 行号; //行号
} 函数调试S;   //在函数中的调试结构

typedef struct {
   对象头S objHeader;
   ByteBuffer instrStream;  //函数编译后的指令流
   ValueBuffer constants;   // 函数中的常量表

   模块对象S* module;    //本函数所属的模块

   //本函数最多需要的栈空间,是栈使用空间的峰值
   uint32_t maxStackSlotUsedNum;
   uint32_t upvalueNum;	  //本函数所涵盖的upvalue数量
   uint8_t argNum;   //函数期望的参数个数
#if DEBUG
   函数调试S* debug;
#endif
} 函数对象S;   //函数对象

typedef struct upvalue {
   对象头S objHeader;

   //栈是个Value类型的数组,localVarPtr指向upvalue所关联的局部变量
   Value* localVarPtr;

   //已被关闭的upvalue
   Value closedUpvalue;

   struct upvalue* next;   //用以链接openUpvalue链表
} 上一层对象S;   //upvalue对象

typedef struct {
   对象头S objHeader;
   函数对象S* fn;   //闭包中所要引用的函数

   上一层对象S* upvalues[0]; //用于存储此函数的 "close upvalue"
} 闭包对象S;	  //闭包对象

typedef struct {
   uint8_t* ip;    //程序计数器 指向下一个将被执行的指令

   //在本frame中执行的闭包函数
   闭包对象S* closure;

   //frame是共享therad.stack
   //此项用于指向本frame所在threadruntime栈的起始地址
   Value* stackStart;
} 调用框架S;  //调用框架

#define INITIAL_FRAME_NUM 4

上一层对象S* 创建上一层值对象(虚拟机* 虚拟机S, Value* localVarPtr);
闭包对象S* 以函数fn创建一个闭包(虚拟机* 虚拟机S, 函数对象S* objFn);
函数对象S* 新建一个空函数(虚拟机* 虚拟机S, 模块对象S* objModule, uint32_t maxStackSlotUsedNum);
/**************************************************o_obj_fn.h-结束**************************************************/
/**************************************************o_obj_thread.h-开始**************************************************/
typedef struct objThread {
   对象头S objHeader;

   Value* stack;  //runtime栈的栈底
   Value* esp;    //runtime栈的栈顶
   uint32_t stackCapacity;  //栈容量

   调用框架S* frames;   //调用框架
   uint32_t usedFrameNum;   //已使用的frame数量
   uint32_t frameCapacity;  //frame容量

   //"打开的upvalue"的链表首结点
   上一层对象S* openUpvalues;

   //当前thread的调用者
   struct objThread* caller;

   //导致runtime错误的对象会放在此处,否则为空
   Value errorObj;
} 线程对象S;    //线程对象

void 为运行函数准备桢栈(线程对象S* objThread, 闭包对象S* objClosure, Value* stackStart);
线程对象S* 新建线程(虚拟机* 虚拟机S, 闭包对象S* objClosure);
void 重置线程(线程对象S* objThread, 闭包对象S*  objClosure);
/**************************************************o_obj_thread.h-结束**************************************************/
/**************************************************o_debug.h-开始**************************************************/
#ifdef DEBUG
   void bindDebugFnName(虚拟机* 虚拟机S, 函数调试S* fnDebug,
	 const char* name, uint32_t 长度);
   void bindDebugFnName2(虚拟机* 虚拟机S, 函数对象S* fn,
	   const char* name, uint32_t 长度);


   void dumpValue(Value value);
   void dumpInstructions(虚拟机* 虚拟机S, 函数对象S* fn);
   void dumpStack(线程对象S* thread);

   void fdumpValue(Value value);
   void fdumpInstructions(虚拟机* 虚拟机S, 函数对象S* fn);
   void fdumpStack(线程对象S* thread);

   FILE* gfnFile;
#endif
/**************************************************o_debug.h-结束**************************************************/
/**************************************************o_类.h-开始**************************************************/
   typedef enum {
      方法类型_空类型,     //空方法类型,并不等同于undefined
      方法类型_原生,    //在vm中用c实现的原生方法
      方法类型_脚本,	//脚本中定义的方法
      方法类型_函数对象的调用,  //有关函数对象的调用方法,用来实现函数重载
   } 方法类型S;
   /*用于把ValueType类型转换为Value结构。*/
   #define VT_TO_VALUE(vt) ((Value){vt, {0}})

   #define BOOL_TO_VALUE(编译bool) (编译bool ? VT_TO_VALUE(值类型_真) : VT_TO_VALUE(值类型_假))/*把BOOL类型转换为Value结构*/
   #define VALUE_TO_BOOL(value) ((value).type == 值类型_真 ? true : false)

   #define NUM_TO_VALUE(num) ((Value){值类型_数字, {num}})
   #define VALUE_TO_NUM(value) value.num

   #define OBJ_TO_VALUE(objPtr) (({ Value value; value.type = 值类型_对象; value.objHeader = (对象头S*)(objPtr); value;}))
   #define SET_VALUE_OBJ(obj,objPtr) { Value *value=(obj); value->type=值类型_对象,value->objHeader =(对象头S*)(objPtr);}

   #define VALUE_TO_OBJ(value) (value.objHeader)
   #define VALUE_TO_OBJSTR(value) ((字符串对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJFN(value) ((函数对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJRANGE(value) ((范围对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJINSTANCE(value) ((对象实例S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJLIST(value) ((list对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJMAP(value) ((map对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJCLOSURE(value) ((闭包对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJTHREAD(value) ((线程对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_OBJMODULE(value) ((模块对象S*)VALUE_TO_OBJ(value))
   #define VALUE_TO_CLASS(value) ((Class*)VALUE_TO_OBJ(value))

   #define VALUE_IS_UNDEFINED(value) ((value).type == 值类型_未定义)
   #define VALUE_IS_NULL(value) ((value).type == 值类型_空)
   #define VALUE_IS_TRUE(value) ((value).type == 值类型_真)
   #define VALUE_IS_FALSE(value) ((value).type == 值类型_假)
   #define VALUE_IS_NUM(value) ((value).type == 值类型_数字)
   #define VALUE_IS_OBJ(value) ((value).type == 值类型_对象)
   #define VALUE_IS_CERTAIN_OBJ(value, objType) (VALUE_IS_OBJ(value) && VALUE_TO_OBJ(value)->type == objType)
   #define VALUE_IS_OBJSTR(value) (VALUE_IS_CERTAIN_OBJ(value, 对象类型_字符串))
   #define VALUE_IS_OBJINSTANCE(value) (VALUE_IS_CERTAIN_OBJ(value, 对象类型_对象实例))
   #define VALUE_IS_OBJCLOSURE(value) (VALUE_IS_CERTAIN_OBJ(value, 对象类型_闭包))
   #define VALUE_IS_OBJRANGE(value) (VALUE_IS_CERTAIN_OBJ(value, 对象类型_范围))
   #define VALUE_IS_CLASS(value) (VALUE_IS_CERTAIN_OBJ(value, 对象类型_类))
   #define VALUE_IS_0(value) (VALUE_IS_NUM(value) && (value).num == 0)

   //原生方法指针
   typedef bool (*Primitive)(虚拟机* 虚拟机S, Value* args);

   typedef struct {
      方法类型S type;  //union中的值由type的值决定。方法的类型
      union {
         //指向脚本方法所关联的c实现
         Primitive primFn;

         //指向脚本代码编译后的ObjClosure或ObjFn
         闭包对象S* obj;
      };
   } Method;

   声明缓冲区类型M(Method)

   //类是对象的模板
   struct class {
      对象头S objHeader;
      struct class* superClass; //父类
      uint32_t fieldNum;	   //本类的字段数,包括基类的字段数
      MethodBuffer methods;   //本类的方法
      字符串对象S* name;   //类名
   };  //对象类

   typedef union {
      uint64_t bits64;
      uint32_t bits32[2];
      double num;
   } 位64S;

   #define 容量增长因子M 4
   #define 最小容量M 64
   bool 是否相等(Value a, Value b);
   Class* 新建一个裸类(虚拟机* 虚拟机S, const char* name, uint32_t fieldNum);
   Class* 获取对象所属的类(虚拟机* 虚拟机S, Value object);
   Class* 新建一个类(虚拟机* 虚拟机S, 字符串对象S* className, uint32_t fieldNum, Class* superClass);

   //__inline Value ObjToValue(void* objPtr);
/**************************************************o_类.h-结束**************************************************/
/**************************************************o_obj_map.h-开始**************************************************/
#define MAP_LOAD_PERCENT 0.8

typedef struct {
   Value key;
   Value value;
} Entry;   //key->value对儿

typedef struct {
   对象头S objHeader;
   uint32_t 数组容量; //Entry的容量(即总数),包括已使用和未使用Entry的数量
   uint32_t count;  //map中使用的Entry的数量
   Entry* entries; //Entry数组
} map对象S;

map对象S* 新建map对象(虚拟机* 虚拟机S);

void 在map中实现key与value的关联(虚拟机* 虚拟机S, map对象S* objMap, Value key, Value value);
Value 在map中查找key对应的value(map对象S* objMap, Value key);
void 回收map中entry占用的空间(虚拟机* 虚拟机S, map对象S* objMap);
Value 删除map中的key(虚拟机* 虚拟机S, map对象S* objMap, Value key);
/**************************************************o_obj_map.h-结束**************************************************/
/**************************************************o_obj_range.h-开始**************************************************/
typedef struct {
   对象头S objHeader;
   int from;   //范围的起始
   int to;     //范围的结束
} 范围对象S;    //range对象

范围对象S* 新建范围对象(虚拟机* 虚拟机S, int from, int to);
/**************************************************o_obj_range.h-结束**************************************************/
/**************************************************o_语法分析.h-开始**************************************************/
#define MAX_LOCAL_VAR_NUM 128
#define MAX_UPVALUE_NUM 128
#define MAX_ID_LEN 128   //变量名最大长度

#define MAX_METHOD_NAME_LEN MAX_ID_LEN
#define MAX_ARG_NUM 16

//函数名长度+'('+n个参数+(n-1)个参数分隔符','+')'
#define MAX_SIGN_LEN MAX_METHOD_NAME_LEN + MAX_ARG_NUM * 2 + 1

#define MAX_FIELD_NUM 128

typedef struct {
   //如果此upvalue是直接外层函数的局部变量就置为true,
   //否则置为false
   bool 是外层局部变量;

   //外层函数中局部变量的索引或者外层函数中upvalue的索引
   //这取决于isEnclosing局部变量S的值
   uint32_t index;
} 上一层值S;  //upvalue结构

typedef struct {
   const char* name;
   uint32_t 长度;
   int 范围深度;  //局部变量作用域

//表示本函数中的局部变量是否是其内层函数所引用的upvalue,
//当其内层函数引用此变量时,由其内层函数来设置此项为true.
   bool isUpvalue;
} 局部变量S;    //局部变量

typedef enum {
   签名_构造函数,  //构造函数
   签名_普通方法,  //普通方法
   签名_getter方法, //getter方法
   签名_setter方法, //setter方法
   签名_getter形式的下标, //getter形式的下标
   签名_setter形式的下标   //setter形式的下标
} 方法签名类型E;   //方法的签名

typedef struct {
   方法签名类型E type;  //签名类型
   const char* name;	//签名
   uint32_t 长度;	//签名长度
   uint32_t argNum;	//参数个数
} 签名S;		//签名

typedef struct loop {
   int condStartIndex;   //循环中条件的地址
   int bodyStartIndex;   //循环体起始地址
   int 范围深度;  //循环中若有break,告诉它需要退出的作用域深度
   int exitIndex;   //循环条件不满足时跳出循环体的目标地址
   struct loop* enclosing循环S;   //外层循环
} 循环S;   //loop结构

typedef struct {
   字符串对象S* name;	      //类名
   SymbolTable fields;	      //类属性符号表
   bool inStatic;	      //若当前编译静态方法就为真
   IntBuffer instantMethods;  //实例方法
   IntBuffer staticMethods;   //静态方法
   签名S* signature;      //当前正在编译的签名
} 类记录信息S;    //用于记录类编译时的信息

typedef struct 编译单元S 编译单元S;

int 定义模块变量(虚拟机* 虚拟机S, 模块对象S* objModule, const char* name, uint32_t 长度, Value value);

函数对象S* 编译模块(虚拟机* 虚拟机S, 模块对象S* objModule, const char* moduleCode);
uint32_t 获取操作码的操作数占用的字节数(Byte* instrStream, Value* constants, int ip);
void 编译单元可达(虚拟机* 虚拟机S, 编译单元S* cu);
/**************************************************o_语法分析.h-结束**************************************************/
/**************************************************o_词法分析.h-开始**************************************************/
typedef enum {
   TOKEN_UNKNOWN,
   // 数据类型
   TOKEN_NUM,		   //数字
   TOKEN_STRING,     	   //字符串
   TOKEN_ID,	     	   //变量名
   TOKEN_INTERPOLATION,     //内嵌表达式

   // 关键字(系统保留字)
   TOKEN_VAR,		   //'var'
   TOKEN_FUN,		   //'fun'
   TOKEN_IF,		   //'if'
   TOKEN_ELSE,	     	   //'else'
   TOKEN_TRUE,	     	   //'true'
   TOKEN_FALSE,	     	   //'false'
   TOKEN_WHILE,	     	   //'while'
   TOKEN_FOR,	     	   //'for'
   TOKEN_BREAK,	     	   //'break'
   TOKEN_CONTINUE,         //'continue'
   TOKEN_RETURN,     	   //'return'
   TOKEN_NULL,	     	   //'null'

   //以下是关于类和模块导入的token
   TOKEN_CLASS,	     	   //'class'
   TOKEN_THIS,	     	   //'this'
   TOKEN_STATIC,     	   //'static'
   TOKEN_IS,		   // 'is'
   TOKEN_SUPER,	     	   //'super'
   TOKEN_IMPORT,     	   //'import'

   //分隔符
   TOKEN_COMMA,		   //','
   TOKEN_COLON,		   //':'
   TOKEN_LEFT_PAREN,	   //'('
   TOKEN_RIGHT_PAREN,	   //')'
   TOKEN_LEFT_BRACKET,	   //'['
   TOKEN_RIGHT_BRACKET,	   //']'
   TOKEN_LEFT_BRACE,	   //'{'
   TOKEN_RIGHT_BRACE,	   //'}'
   TOKEN_DOT,		   //'.'
   TOKEN_DOT_DOT,	   //'..'

   //简单双目运算符
   TOKEN_ADD,		   //'+'
   TOKEN_SUB,		   //'-'
   TOKEN_MUL,		   //'*'
   TOKEN_DIV,		   //'/'
   TOKEN_MOD,		   //'%'

   //赋值运算符
   TOKEN_ASSIGN,	   //'='

   // 位运算符
   TOKEN_BIT_AND,	   //'&'
   TOKEN_BIT_OR,	   //'|'
   TOKEN_BIT_NOT,	   //'~'
   TOKEN_BIT_SHIFT_RIGHT,  //'>>'
   TOKEN_BIT_SHIFT_LEFT,   //'<<'

   // 逻辑运算符
   TOKEN_LOGIC_AND,	   //'&&'
   TOKEN_LOGIC_OR,	   //'||'
   TOKEN_LOGIC_NOT,	   //'!'

   //关系操作符
   TOKEN_EQUAL,		   //'=='
   TOKEN_NOT_EQUAL,	   //'!='
   TOKEN_GREATE,	   //'>'
   TOKEN_GREATE_EQUAL,	   //'>='
   TOKEN_LESS,		   //'<'
   TOKEN_LESS_EQUAL,	   //'<='

   TOKEN_QUESTION,	   //'?'

   //文件结束标记,仅词法分析时使用
   TOKEN_EOF		   //'EOF'
} 单词类型E;

typedef struct {
   单词类型E type;
   const char* start;/*start指针指向源码串中单词的起始地址*/
   uint32_t 长度;/*此单词长度*/
   uint32_t 行号;/*单词所在源码中的行号*/
   Value value;
} 单词S;/*单词S:词法分析器合成单词周边信息的复合结构token.*/
/*词法分析器结构*/
struct 词法分析器S {
   const char* 源码文件名;
   const char* 源码字符串;
   const char* 源码字符串的下一个字符;
   char 当前字符;
   单词S 当前单词;
   单词S 前一个单词;
   模块对象S* 当前正在编译的模块;
   编译单元S* 当前编译单元;
   int 应该插入的右括号数;                /*处于内嵌表达式之中时,期望的右括号数量.用于跟踪小括号对儿的嵌套*/
   struct 词法分析器S* 父词法分析器;
   虚拟机* 虚拟机S;
};

#define PEEK_TOKEN(parserPtr) parserPtr->当前单词.type

char 向前看一个字符(词法分析器* 词法分析器S);
void o_取下个单词(词法分析器* 词法分析器S);
bool 匹配单词(词法分析器* 词法分析器S, 单词类型E expected);
void 断言当前单词为expected(词法分析器* 词法分析器S, 单词类型E expected, const char* 错误信息);
void 断言下一个单词为expected(词法分析器* 词法分析器S, 单词类型E expected, const char* 错误信息);
uint32_t 按照UTF8编码的字节数(int value);
uint8_t 按照UTF8编码写入缓冲区(uint8_t* buf, int value);
void 初始化词法分析器(虚拟机* 虚拟机S, 词法分析器* 词法分析器S, const char* 源码文件名, const char* 源码字符串, 模块对象S* objModule);
/**************************************************o_词法分析.h-结束**************************************************/
/**************************************************o_虚拟机.h-开始**************************************************/
//为定义在opcode.inc中的操作码加上前缀"OPCODE_"
#define 操作码_插槽(opcode, effect) OPCODE_##opcode,

//最多临时根对象数量
#define 最多临时根对象数量M 32

typedef enum {
   #include "o_opcode.inc"
} 操作码S;
#undef 操作码_插槽

typedef enum vmResult {
   虚拟机执行结果_成功,
   虚拟机执行结果_错误
} 虚拟机执行结果S;   //虚拟机执行结果
//如果执行无误,可以将字符码输出到文件缓存,避免下次重新编译

//灰色对象信息结构
typedef struct {
   //gc中的灰对象(也是保留对象)指针数组
   对象头S** grayObjects;
   uint32_t 数组容量;
   uint32_t count;
} 灰色S;

typedef struct {
   //堆生长因子
   int heapGrowthFactor;

   //初始堆大小,默认为10MB
   uint32_t 初始堆大小;

   //最小堆大小,默认为1MB
   uint32_t 最小堆大小;

   //第一次触发gc的堆大小,默认为initialHeapSize
   uint32_t nextGC;
} 配置S;

struct 虚拟机S {
   Class* classOfClass;
   Class* objectClass;
   Class* stringClass;
   Class* mapClass;
   Class* rangeClass;
   Class* listClass;
   Class* nullClass;
   Class* boolClass;
   Class* numClass;
   Class* fnClass;
   Class* threadClass;

   uint32_t 系统已分配的总内存;
   对象头S* 所有已分配对象链表;
   SymbolTable 所有类的方法名称;
   map对象S* allModules;
   线程对象S* 当前正在执行的线程;
   词法分析器* 当前词法分析器;

   //临时的根对象集合(数组),存储临时需要被GC保留的对象,避免回收
   对象头S* 临时的根对象集合[最多临时根对象数量M];
   uint32_t tmpRootNum;

   //用于存储存活(保留)对象
   灰色S grays;
   配置S config;
};

void 初始化虚拟机(虚拟机* 虚拟机S);
虚拟机* 新建虚拟机(void);
void 确保栈有效(虚拟机* 虚拟机S, 线程对象S* objThread, uint32_t neededSlots);
虚拟机执行结果S 执行指令(虚拟机* 虚拟机S, register 线程对象S* 当前正在执行的线程);
void 将obj作为临时根对象(虚拟机* 虚拟机S, 对象头S* obj);
void 去掉临时根对象(虚拟机* 虚拟机S);
void 释放虚拟机(虚拟机* 虚拟机S);
/**************************************************o_虚拟机.h-结束**************************************************/

/**************************************************o_垃圾回收.h-开始**************************************************/
void 标灰对象(虚拟机* 虚拟机S, 对象头S* obj);
void 标灰值(虚拟机* 虚拟机S, Value value);
void 释放对象自身及其占用的内存(虚拟机* 虚拟机S, 对象头S* obj);
void 运行垃圾回收器(虚拟机* 虚拟机S);
/**************************************************o_垃圾回收.h-结束**************************************************/
/**************************************************o_core.h-开始**************************************************/
extern char* 根目录;
char* 读取源代码文件(const char* sourceFile);
虚拟机执行结果S 执行模块(虚拟机* 虚拟机S, Value moduleName, const char* moduleCode);
int 从符号表获取符号索引(SymbolTable* table, const char* symbol, uint32_t 长度);
int 添加符号(虚拟机* 虚拟机S, SymbolTable* table, const char* symbol, uint32_t 长度);
void 创建核心模块(虚拟机* 虚拟机S);
void 绑定方法(虚拟机* 虚拟机S, Class* class, uint32_t index, Method method);
void 绑定基类(虚拟机* 虚拟机S, Class* subClass, Class* superClass);
int 确保符号已经添加到符号表(虚拟机* 虚拟机S, SymbolTable* table, const char* symbol, uint32_t 长度);
/**************************************************o_core.h-结束**************************************************/
/**************************************************o_obj_list.h-开始**************************************************/
typedef struct {
   对象头S objHeader;
   ValueBuffer elements;  //list中的元素
} list对象S;  //list对象

list对象S* 新建list对象(虚拟机* 虚拟机S, uint32_t elementNum);
Value 删除list中索引值为index的元素(虚拟机* 虚拟机S, list对象S* objList, uint32_t index);
void 在list对象index索引处插入值(虚拟机* 虚拟机S, list对象S* objList, uint32_t index, Value value);
/**************************************************o_obj_list.h-结束**************************************************/



#endif
